﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Serialization;
using System.Collections.ObjectModel;
using System.Xml;
using System.IO;

namespace VRacer
{
    /// <summary>
    /// Kolekcja zawierajaca najlepsze wyniki dla danej trasy.
    /// Obiekt tej klasy moze byc wczytany z pliku XML z pomoca statycznej metody Create, oraz zapisany przy pomocy metody Save.
    /// Umozliwia takze scalenie dwoch kolekcji za pomocą metody Update.
    /// </summary>
    [XmlRoot("Highscores")]
    public class Highscores : ObservableCollection<Score>
    {

        public void Add(PlayerBase player)
        {
            var score = new Score(player.Title, player.Statistics.Moves);

            score.Save = player is HumanPlayer;

            this.Add(score);
        }

        /// <summary>
        /// Scala dwie kolekcje wynikow
        /// </summary>
        /// <param name="highscores">The highscores.</param>
        public void Update(Highscores highscores)
        {
            foreach (var score in highscores)
                if(score.Save)
                    this.Add(score);
        }

        /// <summary>
        /// Wczytuje najlepsze wyniki z pliku.
        /// </summary>
        /// <param name="scoresFile">Pelna sciezka do pliku</param>
        /// <returns></returns>
        public static Highscores Create(string scoresFile)
        {
            if (File.Exists(scoresFile))
            {
                XmlReader reader = XmlReader.Create(scoresFile, new XmlReaderSettings());
                try
                {
                    XmlSerializer serializer = new XmlSerializer(typeof(Highscores));
                    return (Highscores)serializer.Deserialize(reader);
                }
                catch (Exception e)
                {
                    throw new Exceptions.CannotReadHighscoresException(e);
                }
                finally
                {
                    reader.Close();
                }
            }

            return new Highscores();
        }

        /// <summary>
        /// Zapisuje najlepsze wyniku do pliku
        /// </summary>
        /// <param name="scoresFile">Pelna sciezka do pliku</param>
        public void Save(string scoresFile)
        {
            var writer = XmlWriter.Create(scoresFile, new XmlWriterSettings()
            {
                Indent = true
            });
            try
            {
                XmlSerializer serializer = new XmlSerializer(typeof(Highscores));
                serializer.Serialize(writer, this);
            }
            catch (Exception e)
            {
                throw new Exceptions.CannotWriteHighscoresException(e);
            }
            finally
            {
                writer.Close();
            }
        }
    }
}
